package com.inspur.icity.bus.api.user.service;

import com.inspur.icity.bus.api.user.model.*;
import com.inspur.icity.bus.api.user.repo.BusRouteDao;
import com.inspur.icity.bus.base.core.inspurresult.*;
import com.inspur.icity.bus.base.core.service.CrudService;
import com.inspur.icity.bus.base.core.util.DateUtil;
import com.inspur.icity.bus.base.core.util.GaodeMapApi;
import com.inspur.icity.bus.base.core.util.InspurApi;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 线路Service
 */
@Service
public class BusRouteService extends CrudService<BusRouteDao, BusRoute, Integer> {

    @Autowired
    private BusSearchHistoryService busSearchHistoryService;

    @Autowired
    private BusRouteHistoryService busRouteHistoryService;

    @Autowired
    private BusSiteService busSiteService;

    @Autowired
    private BusBaseDataService busBaseDataService;


    /**
     * 获取线路详情
     * @param areacode 系统代码
     * @param routeName 线路名称
     * @param direction 描述
     * @param flag 标记是否需记录历史
     * @param mobile
     * @param longitude
     * @param latitude
     * @param isSave 是否记录搜索历史
     * @return
     */
    @Transactional
    public Map<String,Object> getRouteDetails(String areacode, String routeName, String direction, Integer updown, String flag, String mobile, Double longitude, Double latitude, String isSave, Boolean isTnterval){
        Map lineDetailMap = new HashedMap();
        List<Map<String,Object>> siteList = new ArrayList<>();

        //获取基础数据
        Map<String,Object> map = new HashMap<>();
        map.put("code",areacode);
        List<BusBaseData> list = busBaseDataService.find(map);
        if(null == list || list.size() == 0){
            return null;
        }
        BusBaseData busBaseData = list.get(0);

        Map<String,Object> params = new HashedMap();
        params.put("areacode",areacode);
        params.put("routeName",routeName);
        params.put("direction",direction);
        params.put("updown",updown);

        //查询线路信息
        List<BusRoute> routes = find(params);

        if(null == routes || routes.size() <= 0){
            params.remove("updown"); //针对高德数据，环路
            routes = find(params);
        }
        if(null == routes || routes.size() <= 0){
            params.put("updown",updown);
            params.remove("direction"); //针对石家庄，不同跑法（历史数据）
            routes = find(params);
        }
        if(null == routes || routes.size() <= 0){
            //若库中不存在该线路，则重新获取，并更新入库
            BusRouterResult busRouterResult = InspurApi.queryAllRoutes(busBaseData.getIcityUri(),areacode,routeName); //重新查询当前线路
            if (busRouterResult != null && busRouterResult.getStatus() != null && "0000".equals(busRouterResult.getStatus())){
                List<BusRouter> busRouters = busRouterResult.getBusRouters();
                if(null != busRouters && busRouters.size() > 0){
                    //过滤重复线路
                    List<BusRoute> busRouters1 = filterRoute(busRouters,null, areacode);
                    //更新线路站点信息
                    updateRouteAndSite(busRouters1,busBaseData);
                    routes = find(params);
                }
            }
        }
        if(null == routes || routes.size() <= 0){
            return null;
        }
        BusRoute busroute = routes.get(0);
        lineDetailMap.put("startDirection",busroute.getBeginStationName());
        lineDetailMap.put("endDirection",busroute.getEndStationName());
        lineDetailMap.put("updown",busroute.getUpdown());
        lineDetailMap.put("lineName",busroute.getRouteName());
        lineDetailMap.put("lineId",busroute.getRouteId());
        lineDetailMap.put("firstOrder",busroute.getFirstOrder());// 首班时间
        lineDetailMap.put("lastOrder",busroute.getLastOrder());// 末班时间
        lineDetailMap.put("ticket",busroute.getTicket()); //票价

        //查询站点参数
        params.put("updown",updown);
        params.put("routeId",busroute.getRouteId()); //线路ID号

        //查询BUS实时位置
        BusLocationResult busLocationResult = InspurApi.getBusLocation(busBaseData.getIcityUri(),areacode, String.valueOf(busroute.getRouteId()),String.valueOf(busroute.getUpdown()),"");

        // 当前线路不存在车辆，则重新获取线路站点信息，并更新到本地数据库 -- （石家庄一个线路多个跑法）
        if("02".equals(areacode)){
            if(null == busLocationResult || !"0000".equals(busLocationResult.getStatus()) || null == busLocationResult.getBusLocations() || busLocationResult.getBusLocations().size() <= 0){
                BusRouterResult busRouterResult = InspurApi.queryAllRoutes(busBaseData.getIcityUri(),areacode,busroute.getRouteName()); //重新查询当前线路
                if (busRouterResult != null && busRouterResult.getStatus() != null && "0000".equals(busRouterResult.getStatus())){
                    List<BusRouter> busRouters = busRouterResult.getBusRouters();
                    if(null != busRouters && busRouters.size() > 0){
                        //过滤重复线路
                        List<BusRoute> busRouters1 = filterRoute(busRouters,busroute,areacode);
                        //更新线路站点信息
                        updateRouteAndSite(busRouters1,busBaseData);
                        if(null != busRouters1 && busRouters1.size() > 0){
                            //重新获取车辆实时位置
                            busLocationResult = InspurApi.getBusLocation(busBaseData.getIcityUri(),areacode, String.valueOf(busRouters1.get(0).getRouteId()),String.valueOf(busroute.getUpdown()),"");
                            params.put("routeId",busRouters1.get(0).getRouteId()); //重新赋值线路ID号
                        }
                    }
                }
            }
        }
        //计算车辆个数
        lineDetailMap.put("carNo",getCarSum(busLocationResult));

        //查询站点信息，根据站点序号排序
        if("03".equals(areacode) && "0".equals(String.valueOf(updown))){ //滨州市，下行站点数据是反的
            params.put("orderBy","order by stationIndex desc");
        }else{
            params.put("orderBy","order by stationIndex");
        }
        List<BusSite> busSites = busSiteService.find(params);

        if(null == busSites || busSites.size() <= 0){
            params.remove("updown");
            busSites = busSiteService.find(params);
        }
        //获取不到站点数据时，重新调用站点接口
        if(null == busSites || busSites.size() <= 0){
            //调用爱城市网站点接口
            List<BusSite> busSiteList = callSite(busBaseData,busroute);
            if(null != busSiteList && busSiteList.size() > 0){
                busSiteService.batchDelete(busroute); // 批量删除当前上\下行线路的所有站点
                busSiteService.batchSave(busSiteList); // 批量新增当前线路站点信息
            }
            busSites = busSiteService.find(params);
        }

        //封装站点
        Map stationMap = null;
        Integer siteId = getNear(busSites,longitude,latitude);//计算距离最近
        int index = 0;
        String lastCarid ="";
        for(BusSite busSite :  busSites){
            stationMap = new HashedMap();
            stationMap.put("siteName",busSite.getStationName());
            stationMap.put("siteId",busSite.getStationIndex());
            if(null != siteId && siteId.equals(busSite.getId())){
                stationMap.put("isNear",true); //离我最近
            }else{
                stationMap.put("isNear",false);
            }
            stationMap.put("lat",busSite.getLat());
            stationMap.put("lng",busSite.getLng());
            stationMap.put("statue",getCarStatus(busSite.getStationIndex(),busLocationResult,index));
            siteList.add(stationMap);
            if("02".equals(areacode)){ // 石家庄市迭代
                index++;
                if(null != busLocationResult)
                {
                    List<BusLocation> busLocations = busLocationResult.getBusLocations();
                    if(null != busLocations &&busLocations.size()>0)
                    {
                        Integer lastLessIndex = 0;
                        int selectIndex = -1;
                        Integer lastSecondLessIndex = 0;
                        for(int i=0;i<busLocations.size();i++)
                        {
                            Integer stationIndex = busLocations.get(i).getStationIndex();

                            if(stationIndex<=busSite.getStationIndex() && stationIndex>=lastLessIndex)
                            {
                                lastLessIndex=stationIndex;
                                selectIndex = i;
                            }
                        }
                        if(selectIndex>=0 && busLocations.get(selectIndex).getStationIndex()<=busSite.getStationIndex())
                        {
                            BusLocation lastLessBus = busLocations.get(selectIndex);
                            lastCarid = lastLessBus.getCarid();
                            stationMap.put("lastLessBus", lastLessBus);
                        }

                        selectIndex = -1;
                        if(null != busLocations &&busLocations.size()>0)
                        {
                            for(int i=0;i<busLocations.size();i++)
                            {
                                Integer stationIndex = busLocations.get(i).getStationIndex();
                                String busId = busLocations.get(i).getCarid();

                                if(stationIndex<=busSite.getStationIndex() && stationIndex>=lastSecondLessIndex && !busId.equals(lastCarid))
                                {
                                    lastSecondLessIndex=stationIndex;
                                    selectIndex = i;
                                }
                            }
                            if(selectIndex>=0 && busLocations.get(selectIndex).getStationIndex()<=busSite.getStationIndex())
                            {System.out.println(selectIndex);
                                BusLocation lastSecondLessBus = busLocations.get(selectIndex);
                                stationMap.put("lastSecondLessBus", lastSecondLessBus);
                            }
                        }
                    }
                }
            }
        }

        lineDetailMap.put("siteList",siteList);

        //保存当前用户搜索线路，排除济南城际公交
        if(null != flag && "search".equals(flag) && !isTnterval){
            busSearchHistoryService.saveSearchHistory(routeName,direction,updown,busroute.getRouteId(),1,mobile,areacode);
        }
        if(!"no".equals(isSave) && !isTnterval){ //排除济南城际公交、定时任务
            //保存当前用户常用路线
            BusRouteHistory history = new BusRouteHistory();
            history.setMobile(mobile);
            history.setName(routeName);
            history.setDirection(direction);
            history.setUpdown(updown);
            history.setAreacode(areacode);
            history.setCity("");
            history.setDeleted(0);
            history.setCreateTime(DateUtil.getSystemTime());
            busRouteHistoryService.add(history);
        }
        return lineDetailMap;
    }

    /**
     * 调用爱城市网站点接口
     * @param busBaseData
     * @param busroute
     */
    private List<BusSite> callSite(BusBaseData busBaseData, BusRoute busroute) {
        List<BusSite> busSites = new ArrayList<>();
        BusStationResult busStationResult = InspurApi.getStations(busBaseData.getIcityUri(),busroute.getAreacode(), String.valueOf(busroute.getRouteId()), String.valueOf(busroute.getUpdown()));
        if(busStationResult != null && busStationResult.getStatus() != null && "0000".equals(busStationResult.getStatus())){
            List<BusStation> busStations = busStationResult.getBusStations();
            BusSite site = null;
            for(BusStation busStation : busStations){
                site = new BusSite();
                site.setStationName(busStation.getStationName());
                site.setStationIndex(Integer.parseInt(busStation.getStationIndex()));
                site.setLng(Double.parseDouble(busStation.getLongitude()));
                site.setLat(Double.parseDouble(busStation.getLatitude()));
                site.setRouteName(busroute.getRouteName());
                site.setRouteId(busroute.getRouteId());
                site.setAreacode(busroute.getAreacode());
                site.setDirection(busroute.getEndStationName()+"方向");
                site.setUpdown(busroute.getUpdown());
                site.setCreatetime(new Date());
                busSites.add(site);
            }
        }
        return busSites;
    }

    /**
     * 封装线路信息
     */
    public List<BusRoute> filterRoute(List<BusRouter> busRouters,BusRoute busroute,String areaCode) {
        Map<String,String> map = new HashMap<>();
        List<BusRoute> list = new ArrayList<>();
        for (BusRouter busRouter: busRouters){
            if(null != busroute && busroute.getRouteId().equals(busRouter.getRouteid())){ //--针对石家庄不同跑法
                continue;
            }
            String str = busRouter.getRouteName()+busRouter.getUpdown()+busRouter.getRouteid(); //过滤重复线路，按照线路id号、线路名称、上下行
            if(null == map.get(str)) {
                map.put(busRouter.getRouteName() + busRouter.getUpdown() + busRouter.getRouteid(), "");
                //封装对象
                BusRoute busRoute = new BusRoute();
                busRoute.setAreacode(areaCode);
                busRoute.setRouteId(Integer.parseInt(busRouter.getRouteid()));
                busRoute.setRouteName(busRouter.getRouteName());
                busRoute.setUpdown(Integer.parseInt(busRouter.getUpdown()));
                busRoute.setDirection(busRouter.getEndStationName()+"方向"); //方向
                busRoute.setBeginStationName(busRouter.getBeginStationName());
                busRoute.setEndStationName(busRouter.getEndStationName());
                busRoute.setFirstOrder(busRouter.getFirstOrder());
                busRoute.setLastOrder(busRouter.getLastOrder());
                busRoute.setStationCount(Integer.parseInt(busRouter.getStationCount()));
                busRoute.setTicket(busRouter.getTicket()); //票价
                busRoute.setCreateTime(new Date());
                list.add(busRoute);
            }
        }
        return list;
    }

    /**
     * 更新线路、站点信息
     * @param busRoutes
     */
    public void updateRouteAndSite(List<BusRoute> busRoutes,BusBaseData busBaseData) {
        List<BusSite> busSites = new ArrayList<>();
        for (BusRoute route:busRoutes){
            //根据线路调用爱城市网站点接口
            List<BusSite> list = callSite(busBaseData,route);
            busSites.addAll(list);
        }
        curdRepo.batchRemoveByRouteId(busRoutes); //删除库中当前线路信息
        curdRepo.batchSave(busRoutes); //批量新增当前线路站点信息
        busSiteService.batchDelete(busRoutes); // 批量删除当前线路上的所有站点
        busSiteService.batchSave(busSites); // 批量新增当前线路站点信息
    }

    /**
     * 获取线路详情 -- 济南城际公交
     * @param areacode 系统代号
     * @param routeName 线路名称
     * @param direction 线路方向
     */
    public Map<String,Object> getRouteDetailsForJn(String areacode, String routeName, String direction, String flag, String mobile, Double longitude, Double latitude, String isSave, Boolean isTnterval){
        Map<String,Object> lineDetailMap = getRouteDetails(areacode,routeName,direction,null,flag,mobile,longitude,latitude, "no", isTnterval);
        return lineDetailMap;
    }

    /**
     * 剔除未出站的车辆
     * @return
     */
    private Integer getCarSum(BusLocationResult busLocationResult){
        int i = 0;
        Integer siteIndex = 1;
        if(busLocationResult != null && "0000".equals(busLocationResult.getStatus()) && null != busLocationResult.getBusLocations()){
            for(BusLocation busLocation : busLocationResult.getBusLocations()){
                if(siteIndex.equals(busLocation.getStationIndex()) && "0".equals(busLocation.getArrive())){ //开往第一站（即认为未出站）
                    i = i+1;
                }
            }
            return busLocationResult.getBusLocations().size() - i;
        }else {
            return 0;
        }
    }

    /**
     * 获取距离登陆用户最近的站点--即获取两点间距离最短
     * @param busSites
     * @param longitude
     * @param latitude
     * @return
     */
    private Integer getNear(List<BusSite> busSites, Double longitude, Double latitude) {
        if(null == longitude || null == latitude){
            return null;
        }
        if(0 == longitude || 0 == latitude){
            return null;
        }
        double temp = 1000000;
        double distance;
        Integer siteId = null;
        for (BusSite busSite : busSites){
            distance = GaodeMapApi.getDistance(busSite.getLng(), busSite.getLat(),longitude,latitude);
            if(temp > distance){
                temp = distance;
                siteId = busSite.getId();
            }
        }
        return siteId;
    }

    /**
     * 页面显示--站点与车辆实时位置
     * @param siteId
     * @param busLocationResult
     * @return
     */
    public List<Integer> getCarStatus(Integer siteId,BusLocationResult busLocationResult,int index){
        List<Integer> carStatus = new ArrayList<>();
        //3普通站点  4车到站了  5 车在两站中间
        if(busLocationResult == null || !"0000".equals(busLocationResult.getStatus())){
            //没有车辆信息
            carStatus.add(3);
            return carStatus;
        }
        if(busLocationResult.getBusLocations() == null || busLocationResult.getBusLocations().size() == 0){
            carStatus.add(3);
            return carStatus;
        }
        for(BusLocation busLocation : busLocationResult.getBusLocations()){
            if(siteId.equals(busLocation.getStationIndex()) && "1".equals(busLocation.getArrive())){ //到达当前站
                carStatus.add(4);
            }
            if(siteId.equals(busLocation.getStationIndex()) && "0".equals(busLocation.getArrive())){ //开往当前站
                carStatus.add(5);
            }
        }
        if(carStatus.size() == 0){
            carStatus.add(3);
        }
        return carStatus;
    }


    /**
     * 查询线路信息（搜索框调用）
     * @param queryMap
     * @param result
     */
    public void queryBusRouter(Map<String, Object> queryMap, List<Map<String, Object>> result) {

        queryMap.put("group","GROUP BY routeName,updown");
        List<BusRoute> busroutes = find(queryMap);
        for (BusRoute busroute : busroutes){
            Map<String,Object> map = new HashedMap();
            map.put("type",1); //表示线路
            map.put("name",busroute.getRouteName());
            map.put("direction",busroute.getDirection());
            map.put("updown",busroute.getUpdown());
            result.add(map);
        }
    }

    /**
     * 批量保存
     * @param list
     */
    public void batchSave(List<BusRoute> list){
        curdRepo.batchSave(list);
    }

    /**
     * 根据参数获取库中线路个数
     * @param name
     * @param direction
     * @param areacode
     * @return
     */
    public int getRouteCount(String name, String direction, String areacode) {
        return curdRepo.getRouteCount(name,direction,areacode);
    }

    /**
     * 根据参数获取库中线路信息
     * @param
     * @param direction
     * @param areacode
     * @return
     */
    public List<BusRoute> findRouteInfo(String routeName, String direction, String areacode) {
        return curdRepo.findRouteInfo(routeName,direction,areacode);
    }


    /**
     * 删除线路数据
     * @param busRoutes
     */
    public void batchDelete(List<BusRoute> busRoutes) {
        curdRepo.batchRemoveByRouteId(busRoutes);
    }

    /**
     * 获取线路记录数
     * @param busRoute
     * @return
     */
    public int getCount(BusRoute busRoute) {
        return curdRepo.getCount(busRoute);
    }
}